//
//  MazeGameVC+LevelControl.swift
//  MazeGame
//
//  Created by orienthong on 2018/12/20.
//  Copyright © 2018 OrientHong. All rights reserved.
//

import SceneKit
import UIKit

extension MazeGameVC {
    //Control
    func levelControlTouchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let p = touches.first!.location(in: self.sceneView)
        let hitResults = self.sceneView.hitTest(p, options: [:])
        //如果点击关卡按钮
        if hitResults.first?.node.parent?.name?.contains("test") ?? false {
            self.currentPressLevelNode = hitResults.first!.node.parent!
            //1.先Animate按钮
            SCNTransaction.animateWithDuration(0.1, completionBlock: {
                
            }) {
                self.currentPressLevelNode?.position.y += 0.5
            }
        }
    }
    
    func levelControlTouchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        
    }
    
    func levelControlTouchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        //用户swipe了就会cancel
        SCNTransaction.animateWithDuration(0.1, completionBlock: {
            self.currentPressLevelNode = nil
        }) {
            //1.回弹按钮
            self.currentPressLevelNode?.position.y -= 0.5
        }
    }
    
    func levelControlTouchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        //1.先Animate按钮
        SCNTransaction.animateWithDuration(0.1, completionBlock: {
            self.currentPressLevelNode = nil
        }) {
            //1.回弹按钮
            self.currentPressLevelNode?.position.y -= 0.5
            //2.可以做一下加载动画：ToDo
        }
        //准备关卡数据 ToDo
        presentLevel()
    }
    
    //Logic
    //开始游戏
    func presentLevel() {
        
        let testNode = self.prepareGameScene(with: self.configurator.Matrix, entrance: self.configurator.Entrance)
        testNode.opacity = 0.0
        testNode.position = SCNVector3Make(0, self.configurator.cameraHeight, 0)
        self.gameScene.rootNode.addChildNode(testNode)
        
        SCNTransaction.animateWithDuration(1.0, completionBlock: {
            self.sceneView.isUserInteractionEnabled = true
            self.sceneState = .playGame
            self.startGame()
        }) {
            //flip up
            self.sceneView.isUserInteractionEnabled = false
            self.cameraXHandle.rotation.w += Float.pi
            self.sceneView.pointOfView!.position = SCNVector3Make(0, 0, self.configurator.cameraHeight)
            
            self.gameNode.position.y -= 10
            self.gameNode.opacity = 0.0
            testNode.position.y -= self.configurator.cameraHeight
            testNode.opacity = 1.0
        }
    }
    //Todo 根据level准备不同的数据
    private func prepareGameScene(with matrix: [[Int]], entrance: Location) -> SCNNode {
        let node = SCNNode()
        
        //Floor
        let plane = SCNPlane(width: 1, height: 1)
        plane.cornerRadius = 0.1
        plane.firstMaterial?.lightingModel = .physicallyBased
        plane.firstMaterial?.diffuse.contents = UIColor.gray
        plane.firstMaterial?.isDoubleSided = true
        for z in 0 ... matrix.count - 1 {
            for x in 0 ... matrix[0].count - 1 {
                let planeNode = SCNNode(geometry: plane)
                planeNode.eulerAngles = SCNVector3Make(-.pi/2, 0, 0)
                let zPosition = Float(z - matrix.count / 2)
                let xPosition = Float(x - matrix.count / 2)
                let position = SCNVector3Make(xPosition, -0.01, zPosition)
                planeNode.position = position
                node.addChildNode(planeNode)
            }
        }
        
        
        var position: SCNVector3!
        let box = SCNBox(width: 1, height: 1, length: 1, chamferRadius: 0.1)
        box.firstMaterial?.lightingModel = .physicallyBased
        box.firstMaterial?.metalness.contents = UIImage(named: "art.scnassets/gold-scuffed-metal.png")
        box.firstMaterial?.normal.contents = UIImage(named: "art.scnassets/gold-scuffed-normal.png")
        box.firstMaterial?.roughness.contents = UIImage(named: "art.scnassets/gold-scuffed-roughness.png")
        box.firstMaterial?.diffuse.contents = configurator.boxColors.random()
        
        let templateNode = SCNNode(geometry: box)
        
        let tbBox = SCNBox(width: CGFloat(matrix.count+1), height: 1, length: 0.5, chamferRadius: 0.5)
        tbBox.firstMaterial = box.firstMaterial?.copy() as? SCNMaterial
        tbBox.firstMaterial?.diffuse.contents = UIColor.red
        
        let tbNode = SCNNode(geometry: tbBox)
        
        let topBox = tbNode.clone()
        topBox.position = SCNVector3Make(0, 0.5, Float(matrix.count/2) + 0.75)
        node.addChildNode(topBox)
        
        let buttomBox = tbNode.clone()
        buttomBox.position = SCNVector3Make(0, 0.5, -(Float(matrix.count/2) + 0.75))
        node.addChildNode(buttomBox)
        
        let lrBox = SCNBox(width: 0.5, height: 1, length: CGFloat(matrix.count+1), chamferRadius: 0.5)
        lrBox.firstMaterial = tbBox.firstMaterial?.copy() as? SCNMaterial
        
        let lrNode = SCNNode(geometry: lrBox)
        
        let leftBox = lrNode.clone()
        leftBox.position = SCNVector3Make(-(Float(matrix.count/2) + 0.75), 0.5, 0)
        node.addChildNode(leftBox)
        
        let rightBox = lrNode.clone()
        rightBox.position = SCNVector3Make(Float(matrix.count/2) + 0.75, 0.5, 0)
        node.addChildNode(rightBox)
        
        
        for z in 0 ... matrix.count-1 {
            for x in 0 ... matrix[0].count-1 {
                let zPosition = Float(z - matrix.count/2)
                let xPosition = Float(x - matrix.count/2)
                if matrix[z][x] == 1 {
                    let boxNode = templateNode.clone()
                    position = SCNVector3Make(xPosition, 0.5, zPosition)
                    boxNode.name = "gamebox"
                    boxNode.position = position
                    node.addChildNode(boxNode)
                }
            }
            
        }
        
        // position sphereNode
        let sphere = SCNSphere(radius: 0.5)
        sphere.firstMaterial = box.firstMaterial?.copy() as? SCNMaterial
        sphere.firstMaterial?.diffuse.contents = configurator.boxColors.random()
        sphereNode = SCNNode(geometry: sphere)
        
        //        sphere.firstMaterial?.specular.intensity = 1.0
        //        sphere.firstMaterial?.shininess = 0.1;
        //        sphere.firstMaterial?.reflective.contents = UIImage(named: "envmap.jpg");
        //        sphere.firstMaterial?.fresnelExponent = 2;
        
        let zPosition = Float(entrance.z - matrix.count/2)
        let xPosition = Float(entrance.x - matrix.count/2)
        sphereNode.position = SCNVector3Make(xPosition, 0.5, zPosition)
        //        sphereNode.geometry?.shaderModifiers = [.geometry :
        //            """
        //            // Waves Modifier
        //            uniform float Amplitude = 0.2;
        //            uniform float Frequency = 5.0;
        //            vec2 nrm = _geometry.position.xz;
        //            float len = length(nrm)+0.0001; // for robustness
        //            nrm /= len;
        //            float a = len + Amplitude*sin(Frequency * _geometry.position.y + u_time * 10.0);
        //            _geometry.position.xz = nrm * a;
        //            """]
        
        //        let surfaceModifier = try! String(contentsOfFile: Bundle.main.path(forResource: "sm_surf", ofType: "shader")!, encoding: .utf8)
        //        sphereNode.geometry?.shaderModifiers = [.surface: surfaceModifier]
        //        sphereNode.rotation = SCNVector4Make(1, 0, 0, -.pi)
        //        sphereNode.geometry!.firstMaterial!.lightingModel = .lambert
        sphereNode.name = "gameSphere"
        node.addChildNode(sphereNode)
        
        return node
    }
}

